构建和使用 MinGW 交叉工具链的一些记录
=======================================

首先说一下为什么要自己构建 MinGW 交叉工具链。我单位的服务器用着个古老的操作系统，而且没办法联网安装软件，所有的软件都要找相关部门的人复制进去。因为我习惯使用最新的软件，所以我经常复制软件的源代码进服务器，然后自己编译。

构建 MinGW 交叉工具链
-----------------------

这个工作主要参考 Arch Linux 的 mingw-w64 的软件包 PKGBUILD. 从 PKGBUILD 可以注意到，Arch 打包这些软件有循环依赖，例如 mingw-w64-crt 需要 mingw-w64-gcc 构建，而 mingw-w64-gcc 又依赖 mingw-w64-crt. 因此，从头构建整套 MinGW 交叉工具链，照抄 Arch 的构建脚本是不行的。我们要按照构建一般的交叉工具链的方法来做，重点是分析各个组件的依赖关系。

首先要构建的是 mingw-w64-binutils, 它不依赖于其他的 MinGW 包，同时构建其他的包都需要它的汇编器和链接器。

接下来是构建 GCC 和 MinGW 的 C 库。MinGW 的 C 库需要用 MinGW GCC 构建，而 MinGW GCC 在构建的过程中需要 MinGW 的头文件构建 libgcc 等库。所以这些软件中要先构建的是 MinGW 头文件，对应于 Arch 的包 mingw-w64-headers. 构建和安装头文件不需要编译，只需要复制头文件到安装目录就行了。

接下来构建第一份 GCC，我们称它为 stage1-gcc. 它的作用仅用于构建 MinGW 的 C 库。在 GCC configure 的时候，只需要启用 C 语言的支持，并且不构建 libatomic, libssp, libquadmath 这些库。

有 stage1-gcc, 就可以构建 MinGW 的 C 库了。我们需要的是 mingw-crt 和 winpthreads 库，这两个库需要分开构建和安装，先构建并安装 mingw-crt，再构建和安装 winpthreads 即可。

最后构建最终版的 GCC. 配置这份 GCC 就没什么限制了，一般的配置是启用 C,C++ 语言，其他配置选项按照需求启用就行了。

用 MinGW 交叉工具链构建 Windows 版的 LLVM
-----------------------------------------------------------

以构建 LLVM 为例介绍一下 MinGW 交叉工具链的用法。

LLVM 使用 CMake 构建系统，我们可以直接使用系统中安装好的 cmake 和 ninja 去构建 LLVM.

LLVM 在构建的过程中，要使用 llvm-tblgen 生成一些文件，这份 llvm-tblgen 必须是在构建的机器上运行的，所以需要先用系统的工具链构建 llvm-tblgen::

  mkdir build-tblgen
  cd build-tblgen
  cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ../llvm-project-12.0.0.src/llvm
  ninja bin/llvm-tblgen

然后交叉编译 LLVM, 为了演示方便，我们这里只构建 llvm-mc.exe. 要注意 CMake 使用交叉工具链的方法::

  mkdir build
  cd build
  cmake -G Ninja \
    -DCMAKE_SYSTEM_NAME=Windows \
    -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ \
    -DLLVM_TABLEGEN="$(realpath ../build-tblgen/bin/llvm-tblgen)" \
    ../llvm-project-12.0.0.src/llvm
  ninja bin/llvm-mc.exe

